package cn.song.util;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.math3.util.Precision;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 工具类
 *
 * @author SongRenShuo
 * @date 2024/01/23
 */
@Slf4j
@Component
public class Tools {

    private static final String ADDRESS_PATTERN = "^([\u4e00-\u9fa5]{1,10}[自治区|省|市|特别行政区] [\u4e00-\u9fa5]{1,10}[自治州|市|盟|县|区] [\u4e00-\u9fa5]{1,20}[区|市|旗|寺|县|街道|乡|苏木|镇] .{1,200})$";
    private static final String PHONE_PATTERN = "^[1][3,4,5,6,7,8,9][0-9]{9}$";


    /**
     * 保留指定位数的小数 - 四舍五入
     *
     * @param number    要处理的数字
     * @param precision 保留的小数位数
     * @return 保留指定位数小数后的结果
     * @author SongRenShuo
     */
    public static double getDoublePrecision(Double number, int precision) {
        number = number == null ? 0.0 : number;

        return Precision.round(number, precision);
    }

    /**
     * 保留指定位数的小数 - 默认保留两位小数 - 四舍五入
     *
     * @param number 要处理的数字
     * @return 保留指定位数小数后的结果
     * @author SongRenShuo
     */
    public static double getDoublePrecision(Double number) {
        number = number == null ? 0.0 : number;

        return Precision.round(number, 2);
    }

    /**
     * 手机号格式校验
     *
     * @param phone 手机号
     * @return boolean
     * @date 2024/01/05
     * @author SongRenShuo
     */
    public static boolean isValidPhone(String phone) {
        return Pattern.matches(PHONE_PATTERN, phone);
    }


    /**
     * 地址格式校验
     *
     * @param address 地址
     * @return boolean
     * @date 2024/01/05
     * @author SongRenShuo
     */
    public static boolean isValidAddress(String address) {
        boolean matches = Pattern.matches(ADDRESS_PATTERN, address);
        if (!matches) {
            log.error("地址格式不正确：{} 原因：{}", address, "正则未通过");
            return false;
        }

        return true;
    }

    /**
     * 地址格式校验 - 处理详细地址空格
     *
     * @param address 地址
     * @return {@link String } 校验通过返回新地址，校验未通过返回null
     * @date 2024/01/05
     * @author SongRenShuo
     */
    public static String isValidAddressDealWithDetailedAddresses(String address) {
        if (!isValidAddress(address)) {
            return null;
        }
        String[] split = address.split(" ");
        StringBuilder detail = new StringBuilder();
        for (int i = 3; i < split.length; i++) {
            detail.append(split[i]);
        }

        String addressNew = split[0] + " " + split[1] + " " + split[2];
        if (detail.length() > 0) {
            addressNew += " " + detail;
        }
        return addressNew;
    }


    /**
     * 校验不发货地区或校验限制IP
     *
     * @param noAddress   需要限制的地址，多个地址之间用逗号分隔
     * @param takeAddress 需要验证的地址
     * @return 如果需要验证的地址不在noAddress列表中，则返回true；否则返回false
     */
    public static boolean checkGoodsNoAddress(String noAddress, String takeAddress) {
        // 如果限制地址为空或者长度为0，表示没有限制地址，直接返回true
        if (noAddress == null || noAddress.isEmpty()) {
            return true;
        }

        // 将限制地址按照逗号分割成字符串数组，并去除空字符串
        List<String> noAddressList = Arrays.stream(noAddress.split(","))
                .map(String::trim)
                .filter(str -> !str.isEmpty())
                .collect(Collectors.toList());

        // 遍历限制地址列表
        for (String restrictedArea : noAddressList) {
            // 如果需要验证的地址包含当前的限制地址
            if (takeAddress.contains(restrictedArea)) {
                // 返回false，表示需要验证的地址在限制地址列表中
                return false;
            }
        }

        // 如果循环结束都没有找到匹配的限制地址，返回true，表示需要验证的地址不在限制地址列表中
        return true;
    }

    /**
     * 获取(用户端)IP地址
     *
     * @param request 请求
     * @date 2025/03/21
     * @return {@link String }
     * @author SongRenShuo
     */
    public static String getIpAddr(HttpServletRequest request) {
        try {
            String unknown = "unknown";
            String ip = request.getHeader("x-forwarded-for");
            if (ip != null && !ip.isEmpty() && !unknown.equalsIgnoreCase(ip)) {
                // 多次反向代理后会有多个ip值，第一个ip才是真实ip
                ip = ip.split(",")[0];
            }
            if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) {
                ip = request.getHeader("X-Real-IP");
            }
            if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
            String replace = ip.replace(":", ".");
            if (replace.contains("0.0.0.0.0.0.0.1") || replace.contains("localhost") || replace.contains("127.0.0.1")) {
                replace = InetAddress.getLocalHost().getHostAddress();
            }
            System.out.println("获取客户端ip: " + replace);
            return replace;
        } catch (Exception e) {
            if (StrUtil.contains(e.getMessage(), "No thread-bound request found:")) {
                log.error("获取客户端ip异常:{}", e.getMessage());
            } else {
                log.error("获取客户端ip异常:", e);
            }
            return "";
        }
    }

    /**
     * 获取当前登录账户 - zhangHu
     *
     * @param defaultValue 默认值
     * @param request 请求
     * @return {@link String }
     * @date 2024/01/22
     * @author SongRenShuo
     */
    public static String getZhangHu(String defaultValue, HttpServletRequest request) {
        return getZhangHuByKey(defaultValue, request, "zhangHu");
    }

    /**
     * 获取当前登录账户 - name
     *
     * @param defaultValue 默认值
     * @param request 请求
     * @return {@link String }
     * @date 2024/01/22
     * @author SongRenShuo
     */
    public static String getZhangHuName(String defaultValue, HttpServletRequest request) {
        return getZhangHuByKey(defaultValue, request, "name");
    }

    /**
     * 获取当前登录账户 - type
     *
     * @param defaultValue 默认值
     * @param request 请求
     * @return {@link Integer }
     * @date 2024/01/22
     * @author SongRenShuo
     */
    public static Integer getZhangHuType(String defaultValue, HttpServletRequest request) {
        return Convert.toInt(getZhangHuByKey(defaultValue, request, "type"));
    }

    /**
     * 获取当前登录账户 - 指定信息
     *
     * @param defaultValue  默认值
     * @param request 请求
     * @param key  编码
     * @return {@link String }
     * @date 2025/02/26
     * @author SongRenShuo
     */
    public static String getZhangHuByKey(String defaultValue, HttpServletRequest request, String key) {
        try {

            if (StringUtils.isBlank(defaultValue)) {
                String token = request.getHeader("token");
                defaultValue = "";
                if (StringUtils.isNotBlank(token)) {
                    // TODO 临时注释
                    // Map map = JavaWebToken.parserJavaWebToken(token);
                    Map map = new HashMap();
                    if (map != null) {
                        defaultValue = map.get(key).toString();
                    }
                }
            }
            return defaultValue;
        } catch (Exception e) {
            if (StrUtil.contains(e.getMessage(), "No thread-bound request found:")) {
                log.error("获取当前登录账户失败:{}", e.getMessage());
            } else {
                log.error("获取当前登录账户失败:", e);
            }
            return "";
        }
    }


    /**
     * 获取request中所有formData参数
     *
     * @param request 请求
     * @return {@link HashMap }<{@link String }, {@link String }>
     * @date 2024/01/22
     * @author SongRenShuo
     */
    public static Map<String, String> getAllFormDataParameters(HttpServletRequest request) {
        Map<String, String> formData = new HashMap<>();
        try {
            // 获取所有参数名
            Enumeration<String> e = request.getParameterNames();
            // 通过Enumeration类中的hasMoreElements()判断是否还有参数名
            while (e.hasMoreElements()) {
                // 获取当前参数名
                String parameterName = e.nextElement();
                // 再通过request.getParameter("")的方法来获取对应参数名的值
                formData.put(parameterName, request.getParameter(parameterName));
            }
        } catch (Exception e) {
            log.error("获取request中所有formData参数 异常：{}", e.getMessage());
        }
        return formData;
    }

    /**
     * 获取request中所有Body参数
     *
     * @param request 请求
     * @return {@link String }
     * @date 2024/01/22
     * @author SongRenShuo
     */
    public static String getAllBodyParameters(HttpServletRequest request) {
        StringBuilder sb = new StringBuilder();
        try {
            // 获取字符集，默认使用 UTF-8
            String encoding = request.getCharacterEncoding();
            if (encoding == null) {
                encoding = StandardCharsets.UTF_8.name();
            }

            try (InputStream is = request.getInputStream()) {
                byte[] buffer = new byte[8192];
                int bytesRead;
                while ((bytesRead = is.read(buffer)) != -1) {
                    sb.append(new String(buffer, 0, bytesRead, encoding));
                }
            }
        } catch (Exception e) {
            log.error("获取request中所有Body参数 异常：{}", e.getMessage(), e);
        }
        return sb.toString();
    }

    /**
     * 获取request中所有Header参数
     *
     * @param request 请求
     * @return {@link HashMap }<{@link String }, {@link Object }>
     * @date 2024/01/22
     * @author SongRenShuo
     */
    public static HashMap<String, Object> getAllHeaderParameters(HttpServletRequest request) {
        HashMap<String, Object> headerData = new HashMap<>();
        try {
            // 获取所有参数名
            Enumeration<String> e = request.getHeaderNames();
            // 通过Enumeration类中的hasMoreElements()判断是否还有参数名
            while (e.hasMoreElements()) {
                // 获取当前参数名
                String parameterName = e.nextElement();
                // 再通过request.getHeader("")的方法来获取对应参数名的值
                headerData.put(parameterName, request.getHeader(parameterName));
            }
        } catch (Exception e) {
            log.error("获取request中所有Header参数 异常：{}", e.getMessage());
        }
        return headerData;
    }

    /**
     * 排序并拼接
     *
     * @param params 参数
     * @return {@link String }
     * @date 2024/03/21
     * @author SongRenShuo
     */
    public static String createLinkString(Map<String, Object> params) {
        // log.info("排序前 = {}", JSONUtil.toJsonStr(params.toString()));
        List<Map.Entry<String, Object>> list = new ArrayList<>(params.entrySet());
        // 然后通过比较器来实现排序
        // 升序排序
        list.sort(Map.Entry.comparingByKey());
        StringBuilder builder = new StringBuilder();
        for (Map.Entry<String, Object> mapping : list) {
            builder.append(mapping.getKey()).append("=").append(mapping.getValue()).append("&");
        }
        String newStar = builder.substring(0, builder.length() - 1);
        // log.info("拼接后 = {}", newStar);
        return newStar;
    }

    /**
     * 文件上传
     *
     * @param file                文件
     * @param filePath            文件路径
     * @param customFileName      自定义文件名（不含后缀）
     * @param clearExistingFolder 是否清空已存在的文件夹
     * @return 文件地址
     * @author SongRenShuo
     */
    public static String getFileUpload(MultipartFile file, String filePath, String customFileName,
                                       boolean clearExistingFolder) {
        return getFileUpload(file, filePath, customFileName, clearExistingFolder, false);
    }


    /**
     * 文件上传
     *
     * @param file                   文件
     * @param filePath               文件路径
     * @param customFileName         自定义文件名（不含后缀）
     * @param clearExistingFolder    是否清空已存在的文件夹
     * @param whetherOrNotToCompress 是否压缩(默认压缩)
     * @return 文件地址
     * @author SongRenShuo
     */
    public static String getFileUpload(MultipartFile file, String filePath, String customFileName,
                                       boolean clearExistingFolder, boolean whetherOrNotToCompress) {
        if (file == null) {
            return null;
        }

        // 获取原始文件名和后缀
        String originalFileName = file.getOriginalFilename();
        String fileExtension = "";
        if (originalFileName != null) {
            fileExtension = originalFileName.substring(originalFileName.lastIndexOf(".") + 1);
        }
        // 检查自定义文件名是否为空，若为空则使用原始文件名（不含路径和后缀）
        String fileNameToSave = StrUtil.isBlank(customFileName) ? originalFileName : customFileName + "." + fileExtension;
        File dest = new File(filePath + fileNameToSave);
        // 如果需要清空已存在的文件夹
        if (clearExistingFolder && dest.getParentFile().exists()) {
            deleteDirectory(dest.getParentFile());
        }
        // 不存在就创建
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdirs();
        }
        try {
            // 保存文件
            long copy = Files.copy(file.getInputStream(), Paths.get(filePath + fileNameToSave), StandardCopyOption.REPLACE_EXISTING);
            if (whetherOrNotToCompress) {
                Set<String> hashSet = new HashSet<>(Arrays.asList("xbm", "tif", "pjp", "svgz", "jpg", "jpeg", "ico", "tiff", "gif", "svg", "jfif", "webp", "png", "bmp", "pjpeg", "avif"));
                if (hashSet.contains(fileExtension)) {
                    FilePath.compressImageFile(filePath, fileNameToSave);
                }
            }
            // 文件上传成功
            if (copy > 0) {
                return fileNameToSave;
            }
        } catch (IOException e) {
            log.error("文件保存失败", e);
        }

        return null;
    }


    /**
     * 流文件转换文件
     *
     * @param file       文件
     * @param customPath 自定义路径
     * @return {@link File }
     * @date 2024/09/13
     * @author SongRenShuo
     */
    public static File handleFileUpload(MultipartFile file, String customPath) throws IOException {
        // 获取上传的文件名
        String fileName = file.getOriginalFilename();
        if (StringUtils.isBlank(fileName)) {
            throw new IllegalArgumentException("文件名不能为空");
        }

        // 使用FilenameUtils获取后缀名
        String suffix = FilenameUtils.getExtension(fileName);
        // 添加点前缀
        suffix = "." + suffix;
        // 获取文件名
        fileName = FilenameUtils.getBaseName(fileName);

        // 创建自定义路径的对象
        Path customDir = Paths.get(customPath);

        // 确保自定义目录存在
        Files.createDirectories(customDir);

        // 用UUID作为文件名，防止生成的临时文件重复
        File dest = new File(customDir.toFile(), fileName + "_" + UUID.randomUUID().toString().replace("-", "") + suffix);

        // 将上传文件复制到指定路径下的临时文件
        try (InputStream inputStream = file.getInputStream()) {
            FileUtils.copyInputStreamToFile(inputStream, dest);
        }

        return dest;
    }


    /**
     * 删除目录
     *
     * @param directory 目录
     * @date 2023/12/28
     * @author SongRenShuo
     */
    public static void deleteDirectory(File directory) {
        if (directory.exists()) {
            File[] files = directory.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isDirectory()) {
                        deleteDirectory(file);
                    } else {
                        file.delete();
                    }
                }
            }
            directory.delete();
        }
    }

    /**
     * 下载文件
     *
     * @param path     路径
     * @param fileName 文件名
     * @param response 响应
     * @throws IOException ioexception
     */
    @SneakyThrows
    public static void downFile(String path, String fileName, HttpServletResponse response) {
        System.err.println(fileName + "==============");
        // 设置响应内容类型为下载
        response.setContentType("application/x-msdownload");
        // 设置响应头，使浏览器弹出下载框并提示下载文件名
        response.addHeader("Content-Disposition", "attachment;fileName=" + new String(fileName.getBytes(), "iso8859-1"));
        // 获取输出流
        OutputStream os = response.getOutputStream();
        // 创建文件输入流
        FileInputStream fis = new FileInputStream(path);
        try {
            // 创建缓冲输入流
            BufferedInputStream bufferedInputStream = new BufferedInputStream(fis);
            // 创建缓冲输出流
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(os);
            // 创建缓冲区
            byte[] buffer = new byte[4096];
            int count;
            // 循环读取文件内容到缓冲区
            while ((count = bufferedInputStream.read(buffer, 0, buffer.length)) > 0) {
                // 将缓冲区内容写入输出流
                bufferedOutputStream.write(buffer, 0, count);
            }
            bufferedInputStream.close(); // 关闭缓冲输入流
            bufferedOutputStream.flush(); // 刷新缓冲输出流
            bufferedOutputStream.close(); // 关闭缓冲输出流
            os.close(); // 关闭输出流
            fis.close(); // 关闭文件输入流
        } catch (Exception e) {
            log.error("文件下载失败:{}", e.getMessage(), e);
        }
    }


    /**
     * 发送POST请求并返回结果
     *
     * @param urlStr      请求的URL地址
     * @param param       请求的参数
     * @param contentType 请求的内容类型，默认为application/x-www-form-urlencoded; charset=UTF-8
     * @return 返回服务器响应的结果
     */
    public static String sendPost(String urlStr, String param, String contentType) {
        PrintWriter printWriter = null;
        BufferedReader reader = null;
        StringBuilder result = new StringBuilder();
        try {
            // 创建一个URL对象
            URL url = new URL(urlStr);
            // 打开一个HttpURLConnection连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            // 根据ContentType设置请求头
            if (contentType == null) {
                conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            } else {
                conn.setRequestProperty("Content-Type", "application/json");
            }
            // 设置请求头的其他属性
            conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Shuame)");
            // 设置请求方法为POST
            conn.setRequestMethod("POST");
            // 允许输入输出
            conn.setDoInput(true);
            conn.setDoOutput(true);
            // 获取输出流并写入参数
            printWriter = new PrintWriter(conn.getOutputStream());
            printWriter.print(param);
            printWriter.flush();
            printWriter.close();
            // 获取输入流并读取响应内容
            reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            String str;

            while ((str = reader.readLine()) != null) {
                result.append(str);
            }
            reader.close();
            // 打印请求信息
            log.info("sendPost 请求 url:{} param:{} result：{}", urlStr, param, result.toString());
        } catch (Exception e) {
            log.error("sendPost 请求异常 url:{} param:{} 异常信息：{}", urlStr, param, e.getMessage(), e);
        } finally {
            // 关闭资源
            try {
                if (printWriter != null) {
                    printWriter.close();
                }
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        // 返回结果
        return result.toString();
    }

    /**
     * 加密方法，使用MD5算法对明文进行加密
     *
     * @param plainText 需要加密的明文字符串
     * @return 加密后的密文字符串
     */
    public static String encryption(String plainText) {
        String reMd5 = "";
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(plainText.getBytes());
            byte[] b = md.digest();

            int i;

            StringBuilder buf = new StringBuilder();
            for (byte value : b) {
                i = value;
                if (i < 0) {
                    i += 256;
                }
                if (i < 16) {
                    buf.append("0");
                }
                buf.append(Integer.toHexString(i));
            }

            reMd5 = buf.toString();

        } catch (NoSuchAlgorithmException e) {
            log.error("MD5加密失败：{}", e.getMessage(), e);
        }
        return reMd5;
    }


    /**
     * 将给定的浮点数保留三位小数并四舍五入
     *
     * @param d 需要处理的浮点数
     * @return 保留三位小数后的浮点数
     */
    public static double getThreeDecimal(double d) {
        BigDecimal b = new BigDecimal(d);
        return d = b.setScale(3, RoundingMode.HALF_UP).doubleValue();
    }


    /**
     * 创建 SSLSocketFactory 用于双向 SSL 认证
     *
     * @param keyStorePath 证书路径
     * @param keyStorePassword 证书密码，默认为商户号
     * @date 2025/06/26
     * @author SongRenShuo
     * @return SSLSocketFactory 实例
     */
    public static SSLSocketFactory createSSLContext(String keyStorePath, String keyStorePassword, String trustCertPath) {
        try {
            // 1. 加载商户私钥证书（用于客户端身份认证）
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            try (FileInputStream fis = new FileInputStream(keyStorePath)) {
                keyStore.load(fis, keyStorePassword.toCharArray());
            }

            KeyManagerFactory kmf = KeyManagerFactory
                    .getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(keyStore, keyStorePassword.toCharArray());

            // 2. 初始化 SSLContext
            SSLContext sslContext = SSLContext.getInstance("TLSv1.2");

            // 如果信任证书路径为空，则仅使用商户私钥证书
            if (trustCertPath == null || trustCertPath.isEmpty()) {
                sslContext.init(kmf.getKeyManagers(), null, new SecureRandom());
            } else {
                // 加载微信平台证书（用于服务端信任认证）
                CertificateFactory cf = CertificateFactory.getInstance("X.509");
                TrustManagerFactory tmf;
                try (InputStream certStream = Files.newInputStream(Paths.get(trustCertPath))) {
                    X509Certificate caCert = (X509Certificate) cf.generateCertificate(certStream);

                    // 创建信任库
                    KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
                    trustStore.load(null, null);
                    trustStore.setCertificateEntry("wechat", caCert);

                    tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                    tmf.init(trustStore);
                }
                sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
            }

            return sslContext.getSocketFactory();
        } catch (Exception e) {
            log.error("微信支付证书加载失败 证书路径：{} 证书密码：{}", keyStorePath, keyStorePassword, e);
            throw new RuntimeException("微信支付证书加载失败", e);
        }
    }


    /**
     * 获取Map负载因子
     *
     * @param initialCapacity 初始容量
     * @date 2025/07/09
     * @author SongRenShuo
     * @return int
     */
    public static int getMapLoadFactor(Integer initialCapacity) {
        if (initialCapacity == null || initialCapacity <= 0) {
            return 16;
        }
        return (int) (initialCapacity / 0.75f) + 1;
    }
}
